﻿package com.schimanek.display 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.IBitmapDrawable;
	import flash.errors.IllegalOperationError;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author DefaultUser (Tools -> Custom Arguments...)
	 */
	public class DisplayUtils 
	{
		public static const VERTICALLY:String = "vAlign";
		public static const HORIZONTALLY:String = "hAlign";
		public static const LEFT:String = "left";
		public static const RIGHT:String = "right";
		public static const TOP:String = "top";
		public static const BOTTOM:String = "bottom";
		public static const HORIZONTAL_CENTER:String = "hCenter";
		public static const VERTICAL_CENTER:String = "vCenter";
		
		
		public function DisplayUtils() 
		{
			throw new IllegalOperationError("DisplayUtils shall be static");
		}
		/**
		 * Puts the given DisplayObject on top of its DisplayList
		 * @param	DO 	The DisplayObject to set 
		 * 				on top of its siblings	
		 */
		public static function bringToFront(DO:DisplayObject):void {
			DO.parent.setChildIndex(DO, DO.parent.numChildren - 1);			
		}
		/**
		 * 
		 * @param	DO
		 */
		public static function remove(DO:DisplayObject):void {
			DO.parent.removeChild(DO);
			
		}
		/**
		 * Distibutes DisplayObjects
		 * @param	DoList		Array of DOs to be distributet. First one stays where it is.
		 * @param	gap			Gap between Objects
		 * @param	direction	Horizontally or vertically
		 */
		public static function distribute( DoList:Array, gap:Number, direction:String=DisplayUtils.VERTICALLY):void {
			var prevDO:DisplayObject = DoList[0] as DisplayObject;
			var prevBnds:Rectangle = prevDO.getBounds(prevDO.parent);
			
			var currentDO:DisplayObject;
			var currentBnds:Rectangle;
			
			for (var i:int = 1; i <DoList.length ; i++) 
			{
				currentDO = DoList[i] as DisplayObject;
				currentBnds = currentDO.getBounds(currentDO.parent);	
				if(direction==DisplayUtils.HORIZONTALLY){
					currentDO.x =  prevBnds.right + gap + currentDO.x - currentBnds.left;
				}else {
					currentDO.y =  prevBnds.bottom + gap + currentDO.y - currentBnds.top;
				}
				//prepare for next item
				prevDO = currentDO;
				prevBnds = prevDO.getBounds(prevDO.parent);
			}
		}
		/**
		 * Aligns DisplayObjects
		 * @param	DoList		Array of DOs to be aligned. First one stays where it is.		 
		 * @param	alignTo		which bound to align to.
		 * @return 	Array of Points
		 */
		public static function align( DoList:Array, alignTo:String=DisplayUtils.LEFT):Array {
			var prevDO:DisplayObject = DoList[0] as DisplayObject;
			var prevBnds:Rectangle = prevDO.getBounds(prevDO.parent);
			
			var currentDO:DisplayObject;
			var currentBnds:Rectangle;
			
			var aPoint:Array = new Array();
			var rPoint:Point;
			
			aPoint.push(new Point(prevDO.x, prevDO.y));
			for (var i:int = 1; i <DoList.length ; i++) 
			{
				currentDO = DoList[i] as DisplayObject;
				currentBnds = currentDO.getBounds(currentDO.parent);	
				switch (alignTo) {
					case DisplayUtils.LEFT:
						currentDO.x =  prevBnds.left +currentDO.x - currentBnds.left;
						break;
					case DisplayUtils.RIGHT:
						currentDO.x =  prevBnds.right +currentDO.x - currentBnds.right;
						break;	
					case DisplayUtils.HORIZONTAL_CENTER:						
						currentDO.x =  prevBnds.left + (prevBnds.width / 2 - currentBnds.width / 2)-(currentBnds.left-currentDO.x);
						break;
					case DisplayUtils.TOP:
						currentDO.y =  prevBnds.top + currentDO.y - currentBnds.top;						
						break;
					case DisplayUtils.BOTTOM:
						currentDO.y =  prevBnds.bottom + currentDO.y - currentBnds.bottom;						
						break;
					case DisplayUtils.VERTICAL_CENTER:						
						currentDO.y =  prevBnds.top + (prevBnds.height / 2 - currentBnds.height / 2)-(currentBnds.top-currentDO.y);
						break;
				}
				aPoint.push(new Point(currentDO.x, currentDO.y));
				
				//prepare for next item
				prevDO = currentDO;
				prevBnds = prevDO.getBounds(prevDO.parent);
			}
			return aPoint;
		}
		public static function makeBitmap(DO:DisplayObject):Bitmap {
			var bmd:BitmapData = new BitmapData(DO.getBounds(DO.parent).width, DO.getBounds(DO.parent).height, true, 0);			
			bmd.draw(DO);
			return new Bitmap(bmd);
		}
	}
	
}